Introduction



MLTP is the premiere level of competitive Tagpro in North America. Tagpro is a capture the flag game played between two teams of four players; each team typically has two offenders and two defenders in the competitive meta. This data visualization project will showcase some of the primary metrics used to evaluate players and how the stats have changed across modern competitive seasons.

The main statistics used to judge the individual performance of an offender are captures, grabs, scoring percentage, and hold. Captures is the number of times an offender scored, grabs is the number of times an offender picked up the flag, scoring percentage is simply (captures/grabs)*100, the percentage of grabs that result in a capture, and hold is the duration of time an offender has the flag in their possession.

Defenders are mainly judged individually on prevent, tags, and kill/death ratio. Prevent is the duration of time the defender protected the flag from being grabbed, tags are the number of times a player kills a player on the other team, and kill/death ratio is (unsurprisingly) the number of tags divided by the number of deaths.

Finally, team success is typically measured in either win/loss/tie record or by score differential. I will use score differential for the purposes of this data visualization, as a quantitative measure of success is more useful in this case than a qualitative one, as winning by one capture is a much smaller indicator of success than winning by ten captures.



Exploration



Part I: Defense Scatterplots



First, we consider a handful of interactive scatterplots comparing some of the defensive metrics to each other. In each plot, the size of the data point depicts the score differential per minute for that observation. Hovering over each observation will provide the player’s name and their x and y axis values. Each plot also has a slider that controls which season is displayed on the graph; hitting ’Play" will have the plot cycle autonomously through the seasons for a full rotation, and each season can also be directly clicked on manually to jump around.

First, we compare tags per minute to prevent per minute, colored by the main position of the player in each observation. Comparing the two groups, defenders and offenders, gives a schema for what kind of stats a player should be getting for their position:





Next, we remove the offenders from the mix to only see the plot for the defenders. Although seeing the positional differences was useful, reducing the domain and and range of the axes provides a better picture of the subset of players for which the stats are actually important:





Part II: Offense Scatterplots



Now we employ the same technique for hold per minute compared to grabs per minute, again presenting both positions separated by color, and then a subset including only the offenders:







Part III: Distribution Visualization



Beeswarm plots are a magnificent way to visualize distributions of MLTP stats. Beeswarms show the individual observations as unique data points, unlike other distribution visualization techniques which often encode the data abstractly. For example, boxplots uses a box and whiskers to encapsulate all of the non-outlier observations and rely on quartiles and summary statistics. Histograms employ binning to group the data points into bars to display, again obscuring the individual observations. One of the main limitations of beeswarm plots is that for increasingly large datasets, it becomes more and more difficult to show each observation. Modern MLTP seasons typically have somewhere between 32 and 64 majors starters, depending on the number of teams. which falls into the optimal number of observations for a beeswarm plot.

To supplement each beeswarm plot, I have also included an interactive boxplot (a.k.a box-and-whiskers plot) with the individual data points slightly offset from the main body of the boxplot. Hovering over the box for each season will display the summary statistics for that box: Minimum, maximum, first quartile, third quartile, median, and upper fence. Hovering over each data point will give the player’s name, the season the observation was from, and the value from the y-axis, which varies per plot. Toggling the colored boxes in the legend allows the box for each season to be removed or returned to the plot, and double-clicking on any of the boxes will display that season in isolation and remove all other seasons from the boxplot.











## R version 3.6.1 (2019-07-05)
## Platform: x86_64-w64-mingw32/x64 (64-bit)
## Running under: Windows 10 x64 (build 17763)
## 
## Matrix products: default
## 
## locale:
## [1] LC_COLLATE=English_United States.1252 
## [2] LC_CTYPE=English_United States.1252   
## [3] LC_MONETARY=English_United States.1252
## [4] LC_NUMERIC=C                          
## [5] LC_TIME=English_United States.1252    
## 
## attached base packages:
## [1] stats     graphics  grDevices utils     datasets  methods   base     
## 
## other attached packages:
##  [1] beeswarm_0.2.3    pls_2.7-2         factoextra_1.0.6 
##  [4] data.table_1.12.2 plotly_4.9.1      ggfortify_0.4.8  
##  [7] forcats_0.4.0     stringr_1.4.0     dplyr_0.8.3      
## [10] purrr_0.3.2       readr_1.3.1       tidyr_1.0.0      
## [13] tibble_2.1.3      ggplot2_3.2.1     tidyverse_1.2.1  
## 
## loaded via a namespace (and not attached):
##  [1] ggrepel_0.8.1      Rcpp_1.0.2         lubridate_1.7.4   
##  [4] lattice_0.20-38    assertthat_0.2.1   zeallot_0.1.0     
##  [7] digest_0.6.21      mime_0.7           R6_2.4.0          
## [10] cellranger_1.1.0   backports_1.1.4    evaluate_0.14     
## [13] httr_1.4.1         pillar_1.4.2       rlang_0.4.0       
## [16] lazyeval_0.2.2     readxl_1.3.1       rstudioapi_0.10   
## [19] rmarkdown_1.15     htmlwidgets_1.3    munsell_0.5.0     
## [22] shiny_1.3.2        broom_0.5.2        compiler_3.6.1    
## [25] httpuv_1.5.2       modelr_0.1.5       xfun_0.9          
## [28] pkgconfig_2.0.3    htmltools_0.3.6    tidyselect_0.2.5  
## [31] gridExtra_2.3      viridisLite_0.3.0  crayon_1.3.4      
## [34] withr_2.1.2        later_0.8.0        grid_3.6.1        
## [37] nlme_3.1-140       jsonlite_1.6       xtable_1.8-4      
## [40] gtable_0.3.0       lifecycle_0.1.0    magrittr_1.5      
## [43] scales_1.0.0       cli_1.1.0          stringi_1.4.3     
## [46] promises_1.0.1     xml2_1.2.2         generics_0.0.2    
## [49] vctrs_0.2.0        RColorBrewer_1.1-2 tools_3.6.1       
## [52] glue_1.3.1         hms_0.5.1          crosstalk_1.0.0   
## [55] yaml_2.2.0         colorspace_1.4-1   rvest_0.3.4       
## [58] knitr_1.25         haven_2.1.1